package pl.edu.pw.mini.java2.Communicator.Server;

import java.util.*;

/**
 * Klasa odpowiedzialna za zarządzanie klientami.
 * @author Dymitr Załunin, Kamil Łysik.
 */
public class ClientsManager {
	private static ClientsManager instance = null;
	private ClientsCollection clients = null;

	private ArrayList<UpdateContactListListener> handlers = new ArrayList<UpdateContactListListener>();

	public synchronized void setUpdateListHandler(UpdateContactListListener hdn) {
		handlers.add(hdn);
	}

	private ClientsManager() {
		clients = new ClientsCollection();
	}
	
	/**
	 * Generuje zdarzenie wysyłające dostępne kontakty.  
	 * @param list
	 * @param owner
	 */
	public void UpdateHandler(UpdateContactListListener list, String owner){
		Object[] names=clients.GetAllClientsNames();
		for (Object name: names){	
			if (owner.equals((String)name)) continue;
			list.updateAvailableContact((String)name);
		}
	}

	/**
	 * Metoda dokonująca logowania nowego klienta i generująca zdarzenia aktualizowania dostępnych kontaktów.
	 * @param login Login klienta.
	 * @param ch Obiekt obsługujący dodawanego klienta.  
	 */
	public synchronized void Logon(String login, ClientHandler ch) {
		if (clients.FindClientHandler(login) != null) {
			throw new IllegalStateException();
		} else {
			clients.AddClient(login, ch);
			if (handlers != null) {				
				for (UpdateContactListListener h : handlers) {
					h.updateAvailableContact(login);
				}
			}
		}
	}

	private String[] GetClientsArray() {
		String[] list = new String[clients.Count()];
		int i = 0;
		for (Object name : clients.GetAllClientsNames()) {
			list[i] = (String) name;
			i++;
		}
		return list;
	}

	
	/**
	 * Metoda dokonująca wylogowania klienta.
	 * @param login Login klienta.  
	 */
	public synchronized void Logout(String login) {
		clients.RemoveClient(login);		
		if (handlers != null) {				
			for (UpdateContactListListener h : handlers) {
				h.updateLeavingContact(login);
			}
		}
	}

	/**
	 * Metoda 
	 * @param login
	 * @return Obiekt klasy obsługujacej klienta w innym przypadku null.
	 */
	public synchronized ClientHandler FindClient(String login) {
		ClientHandler ch = clients.FindClientHandler(login);
		return ch;
	}

	public synchronized String[] GetAllClientsNames() {
		String[] list = GetClientsArray();
		return list;
	}

	/**
	 * Metoda zwracająca instancję klasy ClientsManager.
	 * @return Referencja do obiektu ClientManager.
	 */
	public static synchronized ClientsManager Instance() {
		if (instance == null)
			instance = new ClientsManager();
		return instance;
	}
}